package org.zjx.message.messages;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.zjx.message.AbstractMessage;

@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RouteResponse extends AbstractMessage {
    // 路由类型
    public enum RouteType {
        DIRECT,      // 直接处理（当前服务器可处理）
        REDIRECT,    // 重定向到其他节点
        UNAVAILABLE  // 服务不可用
    }

    private RouteType routeType;   // 路由类型
    private String targetHost;     // 目标服务器地址（重定向时使用）
    private int targetPort;        // 目标服务器端口（重定向时使用）
    private String serviceName;    // 请求的服务名称
    private String workerId;       // 目标工作节点ID
    private String reason;         // 路由原因（如不可用时的原因）

    // 创建直接处理响应
    public static RouteResponse direct(String serviceName) {
        RouteResponse response = new RouteResponse();
        response.setRouteType(RouteType.DIRECT);
        response.setServiceName(serviceName);
        return response;
    }

    // 创建重定向响应
    public static RouteResponse redirect(String serviceName, String targetHost, int targetPort, String workerId) {
        RouteResponse response = new RouteResponse();
        response.setRouteType(RouteType.REDIRECT);
        response.setServiceName(serviceName);
        response.setTargetHost(targetHost);
        response.setTargetPort(targetPort);
        response.setWorkerId(workerId);
        return response;
    }

    // 创建服务不可用响应
    public static RouteResponse unavailable(String serviceName, String reason) {
        RouteResponse response = new RouteResponse();
        response.setRouteType(RouteType.UNAVAILABLE);
        response.setServiceName(serviceName);
        response.setReason(reason);
        return response;
    }

    // 检查是否是重定向
    public boolean isRedirect() {
        return routeType == RouteType.REDIRECT;
    }

    // 检查是否可直接处理
    public boolean isDirect() {
        return routeType == RouteType.DIRECT;
    }

    // 检查服务是否不可用
    public boolean isUnavailable() {
        return routeType == RouteType.UNAVAILABLE;
    }
}